#include "Common/HmiAdapterRuntime.h"
#include "Layers/View/KEYL_MainView.h"
#include "hmi_service_api.h"
#include "service_manager_api.h"
#include "Scene/Scene.h"
#include "SDL/SDL.h"
#define LOG_TAG "HMI"
#include "log_api.h"
#include "ite/itp.h"
#include <stdint.h>
#include <pthread.h>
#include <time.h>

typedef struct
{
    timer_t  hmiTimer_;
    sem_t    hmiTimeoutSem_;
    bool     isRunning_; 
    char     version[32];
}HmiService;

static HmiService hmiServiceInstance = {
    .version = "HmiService V1.0.0"
};

struct service* hmiServiceoInSystem = NULL;

static void startService()
{
    sem_wait(&hmiServiceInstance.hmiTimeoutSem_);
    hmiServiceInstance.isRunning_ = true;
}

static void serviceLoop()
{
    while(hmiServiceInstance.isRunning_)    // todo weakup or exit ?
    {   
        sem_wait(&hmiServiceInstance.hmiTimeoutSem_);
        
        SceneRun(); // 10 ms
        SystemCountRunning();
    }
}

static void stopService()
{
    if(timer_delete(hmiServiceInstance.hmiTimer_) == -1)
    {
        LOG_D("Delete Timer Fail!");
    }
}

static void hmiMainLoop()
{
    startService();
    serviceLoop();
    stopService();
}

static void handleSystemMessage(struct message *message)
{
    uint16_t id = get_message_id(message);
    switch (id)
    {
        case 1://todo
            selectPage(PAGE_OFF);
            break;

        case 2://todo
            selectPage(PAGE_MAIN);
            break;

        case 3://todo 倒车档需要hmi内部触发
            selectPage(PAGE_BACKUP);
            break;
        
        default:
            LOG_D("Unknow id : %d\n", id);
            break;
    }
}

static void messageHandle(struct service *service, struct message *message, struct message *reply)
{
    uint16_t category = get_message_category(message);
    switch (category)
    {
        case SYSTEM_MESSAGE:
        {
            handleSystemMessage(message);
            break;
        }
        
        default:
        {
            LOG_W("recv unregistered message category:%d\n", category);
        }
    }
}

static void subscriberMessages()
{
    if(hmiServiceoInSystem)
    {
        subscribe(SYSTEM_MESSAGE, hmiServiceoInSystem);
    }
    else
    {
        LOG_E("hmi service init fail!!\n");
    }
}

static void initService()
{
    sem_init(&hmiServiceInstance.hmiTimeoutSem_, 0, 0);
    hmiServiceInstance.isRunning_ = false;
    hmiServiceoInSystem = register_service("hmi_service", 0, 
                                            messageHandle, 
                                            hmiMainLoop, 
                                            &hmiServiceInstance);
	if(!hmiServiceoInSystem) 
    {
		LOG_E("unable to register hmi_service service\n");
	}
    else
    {
        LOG_W("hmi_service init success!\n");
    }
}

static void onTimeout(timer_t timerid, int arg)
{
    sem_post(&hmiServiceInstance.hmiTimeoutSem_);
}

static void initTimer()
{
    struct itimerspec value;
    timer_create(CLOCK_REALTIME, NULL, &hmiServiceInstance.hmiTimer_);
    timer_connect(hmiServiceInstance.hmiTimer_, (VOIDFUNCPTR)onTimeout, 0);
    value.it_value.tv_sec = value.it_interval.tv_sec = 0;
    value.it_value.tv_nsec = value.it_interval.tv_nsec = 17000000;
    timer_settime(hmiServiceInstance.hmiTimer_, 0, &value, NULL);
}

void hmi_service_init()
{   
    initService();
    while(SceneInit() == false) // 8808 ms
    {
        usleep(100000);
    }
    selectPage(PAGE_OFF);
    subscriberMessages();
    initTimer();
}

void hmi_service_destory()
{
    hmiServiceInstance.isRunning_ = false;
}
